package com.card.game.room;

import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.Vector;

import com.card.common.MessageComm;
import com.card.game.BasePlayer;
import com.card.game.BasePlayer.UserState;
import com.card.game.Card;
import com.card.game.CardType;
import com.card.game.CardUtils;
import com.card.game.Player;
import com.card.game.QzUtils;
import com.card.game.event.EventType;
import com.card.main.GameConfig;
import com.card.match.IMatchRoom;
import com.card.match.Match;
import com.card.message.JsonMessageCenter;
import com.card.user.User;
import com.google.common.collect.Lists;
import com.xiaoao.net.common.GameConstants;
import com.xiaoao.net.global.Global;
import com.xiaoao.net.json.message.JsonMessage;
import com.xiaoao.net.utils.StringUtil;

/**   
 * @Description: TODO(用一句话描述该文件做什么) 
 * @author siyunlong   
 * @date 2016年11月7日 下午2:00:15 
 * @version V1.0   
 */
public class MatchRoom extends SHRoom implements IMatchRoom{
	private transient Match match;
	private int curRound;
	private transient boolean allIsEnd;
	private transient List<Card> luckCard = Lists.newArrayList();
	
	public MatchRoom(Match match) {
		super("");
		this.match = match;
//		this.curRound = match.getRound();
		this.isMatchRoom = true;
	}
	
	@Override
	public void addPlayer(User user) {
		Player player = new Player(user);
		synchronized (this.playerList) {
			player.addScore(getBaseScore());
			Player oldPlayer = getPlayerById(player.getUserId());
			if(oldPlayer != null) {
				return;
			}
			this.zhuangId = player.getUserId();
			int tableIndex = randomTableIndex();
			player.setTableIndex(tableIndex);
			this.playerList.add(player);
			player.getUser().setRoom(this);
			match.initScore(player);
			if(this.playerList.size() == getMaxUserNum()) {
				setState(RoomState.Ready);
			}
		}
//		userReady(player.getUserId());
		//通知进入
		sendEnterRoom(player);
	}
	
	@Override
	public void doTimedTask() {
		if(state == RoomState.Ready) {
			long waitTime = System.currentTimeMillis() - this.stateChangeTime;
			if(waitTime > 2*GameConstants.SECOND) {
				checkPlayerState();
				randomSieve();
			}
		}else if(state == RoomState.Running) {
			long waitTime = System.currentTimeMillis() - this.curhowsTurnStartTime;
			if(waitTime > 10*GameConstants.SECOND) {
				autoOutCard();
			}
		}else if(state == RoomState.End && !isEndGame()) {
			long waitTime = System.currentTimeMillis() - this.stateChangeTime;
			if(waitTime > 7*GameConstants.SECOND) {
				checkPlayerState();
				randomSieve();
			}
		}else if(state == RoomState.HuState) {
			long waitTime = System.currentTimeMillis() - this.stateChangeTime;
			if(waitTime > GameConstants.SECOND) {
				setState(RoomState.Running);
				endGame();
				setState(RoomState.End);
			}
		}
	} 
	
	@Override
	public void handOutNoLock(String userId,Card outCard,boolean isTing) {
		Player player = getPlayerById(userId);
		if(player.getTableIndex() != curwhosTurn|| player.getHandSize()%3 != 2	) {
			Global.logErrorMessage(player.getTableIndex()+"========不该你出牌！！！！"+(player.getHandSize()%3 != 2));
			return;
		}
		outCard = player.handOut(outCard,isTing);
		if(outCard.equals(getJinPai())) {
			outCard.setOutJin(true);
		}
		player.getPlayerInfo().setWaitType(null);
		
		this.lastOutCard = outCard;
		this.lastOutCardUser = userId;
		JsonMessage message = new JsonMessage(MessageComm.S2C_HandOut);
		message.addProperty("userId", userId);
		message.addProperty("outCard", outCard);
		message.addProperty("ting", isTing);
		broadcast(message);//广播出牌
		broadTableCard();
		sendUpdateCards(player,true);
		//检查出牌
		checkHandOut(player);
	}
	
	@Override
	public void doLeaveAction(Player player) {
	}
	
	@Override
	public void autoOutCard() {
		if(this.curEvent != null) {
			if(this.curEvent.isZimo()) {
				doSkill(this.curEvent.getUserId(), EventType.ZiMo,0);
			}else{
				JsonMessage message = JsonMessage.createMessage(MessageComm.S2C_DoSkill);
				message.addProperty("type", EventType.Guo.toString());
				message.addProperty("userId", this.curEvent.getUserId());
//				message.addProperty("card", card);
				JsonMessageCenter.getInstance().sendMessage(message, this.curEvent.getUserId());
				doSkill(this.curEvent.getUserId(), EventType.Guo,0);
			}
			return;
		}
		Player curPlayer = getPlayerByTableIndex(this.curwhosTurn);
		if(curPlayer != null) {
//			Global.logErrorMessage(curPlayer.getUserId()+"===========自动出牌===========");
			this.curhowsTurnStartTime = System.currentTimeMillis();
			handOut(curPlayer.getUserId(), curPlayer.getLastInCard(),false);
		}
	}
	
	@Override
	public void enterMatchRoom(String userId) {
		Player player = getPlayerById(userId);
		if(player == null) {
			return;
		}
		player.setState(UserState.Ready);
		if(allIsState(UserState.Ready) && isFull()) {
			sendRoomInfo();
			try {
				Thread.sleep(1000);
			} catch (Exception e) {
			}
			randomSieve();
		}else{
			sendRoomInfo();
		}
	}
	@Override
	public void createTableCard() {
		this.tableCards = CardUtils.createHZCards();
//		this.tableCards = CardUtils.createHZTestCards();
		randomLuckCard();
	}
	
	public void randomLuckCard() {
		try {
			this.luckCard.clear();
			Vector<Card> clones = (Vector<Card>)this.tableCards.clone();
			for (int i = 0; i < 6; i++) {
				int seed = new Random().nextInt(clones.size());
				this.luckCard.add(clones.remove(seed));
			}
		} catch (Exception e) {
		}
	}
	@Override
	public int getNiaoScore() {
		int niao = 0;
		for (Card card : this.luckCard) {
			int index = card.getIndex();
			if(index == 0 || index == 1 || index == 5 || index == 9) {
				niao ++;
			}
		}
		return niao;
	}
	
	@Override
	public boolean isMatchRoom() {
		return true;
	}
	@Override
	public boolean isGameEnd() {
		return allIsEnd;
	}
	@Override
	public List<Card> getShowTingCards(Player player) {
		return QzUtils.getTingCards(player.getHand().cards);
	}
	@Override
	public boolean checkQiangGang(String userId,Card lastInCard,EventType gangType) {
		if(GameConfig.isOnlyZimo
				|| gangType == EventType.AnGang 
				|| gangType == EventType.FangGang 
				|| lastInCard == null
				) {
			return false;
		}
		Player player = getPlayerById(userId);
		Iterator<BasePlayer> it = this.playerList.iterator();
		while (it.hasNext()) {
			Player temp = (Player)it.next();
			if(!StringUtil.equals(userId, temp.getUserId()) && temp.checkQiangGang(this, lastInCard,player)) {
				this.curEvent.setGangType(gangType);
				return true;
			}
		}
		return false;
	}
	public Card getJinPai() {
		return new Card(CardType.ZHONG,0);
	}
	
	@Override
	public void syncMatchScore() {
		for (BasePlayer basePlayer : playerList) {
			match.updateScore(basePlayer);
		}
	}
	
	@Override
	public void calAllGame() {
		this.allIsEnd = true;
		if(!match.isLastLun()) {
			int curLun = match.getCurLun();
			int runNum = match.getRunTableNum();
			for (BasePlayer player : playerList) {
				JsonMessage message = JsonMessage.createMessage(MessageComm.S2C_Match_RoundEnd);
				message.addProperty("curLun", curLun);
				message.addProperty("rank", match.getRank(player.getUserId()));
				message.addProperty("runNum", runNum);
				message.addProperty("canLeave", match.isCanLeave());
				message.addProperty("allUserNum", match.getUserSize());
				message.addProperty("matchName", match.getMatchSetting().getName());
				JsonMessageCenter.getInstance().sendMessage(message, player);		
			}
		}
		clearRoom();
	}
	
	@Override
	public boolean isEndGame() {
		if(this.playNum >= 2) {
			return true;
		}
		return false;
	}
	
	@Override
	public boolean haveJin() {
		return true;
	}
	@Override
	public boolean isCanChi() {
		return false;
	}
	public boolean isHZRoom() {
		return true;
	}
	
	@Override
	public int getMaxUserNum() {
		return 4;
	}

	@Override
	public void clearGameData() {
		super.clearRoom();
	}
	@Override
	public boolean isFull() {
		synchronized (playerList) {
			return this.playerList.size() == getMaxUserNum();
		}
	}
	
	@Override
	public void sendEnterRoom(BasePlayer player) {
		JsonMessage message = new JsonMessage(MessageComm.S2C_Match_EnterRoom);
		message.addProperty("roomId", getId());
		JsonMessageCenter.getInstance().sendMessage(message, player);
	}
	
	@Override
	public void startGame() {
		sendMatchInfo();
		super.startGame();
	}

	@Override
	public void breakConnect(BasePlayer p) {
		super.breakConnect(p);
		sendMatchInfo();
	}
	
	@Override
	public List<Card> getLuckCard() {
		if(gameResult.isLiuJu()) {
			return null;
		}
		return luckCard;
	}

	@Override
	public void sendMatchInfo() {
		int curLun = match.getCurLun();
		int runNum = match.getRunTableNum();
		for (BasePlayer player : playerList) {
			JsonMessage message = new JsonMessage(MessageComm.S2C_Match_Info);
			message.addProperty("userId", player.getUserId());
			message.addProperty("rank", match.getRank(player.getUserId()));
			message.addProperty("allUserNum", match.getUserSize());
			message.addProperty("matchName", match.getMatchSetting().getName());
			message.addProperty("runNum", runNum);
			message.addProperty("curLun", curLun);
			JsonMessageCenter.getInstance().sendMessage(message, player);
		}
	}
}
